<?php
/**
 * 事务类
 */
class Task {
    private $db;
    
    public function __construct() {
        $this->db = Database::getInstance();
    }
    
    /**
     * 创建新事务
     * 
     * @param int $creatorId 创建者ID
     * @param string $title 事务标题
     * @param string $description 事务描述
     * @param string $deadline 截止时间
     * @param array $participantIds 参与者ID数组
     * @return array 包含状态和消息的数组
     */
    public function createTask($creatorId, $title, $description, $deadline, $participantIds = []) {
        // 验证标题
        if (empty($title) || strlen($title) > 100) {
            return ['status' => false, 'message' => '事务标题不能为空且不超过100个字符'];
        }
        
        // 验证截止时间
        if (empty($deadline) || strtotime($deadline) < time()) {
            return ['status' => false, 'message' => '截止时间必须是未来的时间'];
        }
        
        try {
            // 开始事务
            $this->db->getConnection()->beginTransaction();
            
            // 插入事务
            $this->db->query(
                "INSERT INTO tasks (creator_id, title, description, deadline) VALUES (?, ?, ?, ?)",
                [$creatorId, $title, $description, $deadline]
            );
            
            $taskId = $this->db->lastInsertId();
            
            // 添加参与者
            if (!empty($participantIds)) {
                foreach ($participantIds as $participantId) {
                    // 检查是否是男友
                    $friend = new Friend();
                    if ($friend->isFriend($creatorId, $participantId)) {
                        $this->db->query(
                            "INSERT INTO task_participants (task_id, user_id) VALUES (?, ?)",
                            [$taskId, $participantId]
                        );
                        
                        // 添加通知
                        $this->addTaskInvitationNotification($creatorId, $participantId, $taskId, $title);
                    }
                }
            }
            
            // 提交事务
            $this->db->getConnection()->commit();
            
            return [
                'status' => true,
                'message' => '事务创建成功',
                'task_id' => $taskId
            ];
        } catch (Exception $e) {
            // 回滚事务
            $this->db->getConnection()->rollBack();
            return ['status' => false, 'message' => '创建事务失败，请稍后再试'];
        }
    }
    
    /**
     * 更新事务
     * 
     * @param int $taskId 事务ID
     * @param int $userId 当前用户ID
     * @param array $data 要更新的数据
     * @return array 包含状态和消息的数组
     */
    public function updateTask($taskId, $userId, $data) {
        // 检查事务是否存在且用户是创建者
        $task = $this->getTask($taskId);
        if (!$task) {
            return ['status' => false, 'message' => '事务不存在'];
        }
        
        if ($task['creator_id'] != $userId) {
            return ['status' => false, 'message' => '只有事务创建者才能更新事务'];
        }
        
        // 检查事务状态
        if ($task['status'] != 'pending') {
            return ['status' => false, 'message' => '只能更新待处理的事务'];
        }
        
        $allowedFields = ['title', 'description', 'deadline'];
        $updateData = [];
        $params = [];
        
        foreach ($data as $key => $value) {
            if (in_array($key, $allowedFields)) {
                // 验证标题
                if ($key == 'title' && (empty($value) || strlen($value) > 100)) {
                    return ['status' => false, 'message' => '事务标题不能为空且不超过100个字符'];
                }
                
                // 验证截止时间
                if ($key == 'deadline' && (empty($value) || strtotime($value) < time())) {
                    return ['status' => false, 'message' => '截止时间必须是未来的时间'];
                }
                
                $updateData[] = "$key = ?";
                $params[] = $value;
            }
        }
        
        if (empty($updateData)) {
            return ['status' => false, 'message' => '没有要更新的数据'];
        }
        
        $params[] = $taskId;
        
        try {
            $this->db->query(
                "UPDATE tasks SET " . implode(', ', $updateData) . " WHERE id = ?",
                $params
            );
            
            return ['status' => true, 'message' => '事务已更新'];
        } catch (Exception $e) {
            return ['status' => false, 'message' => '更新失败，请稍后再试'];
        }
    }
    
    /**
     * 完成事务
     * 
     * @param int $taskId 事务ID
     * @param int $userId 当前用户ID
     * @return array 包含状态和消息的数组
     */
    public function completeTask($taskId, $userId) {
        // 检查事务是否存在
        $task = $this->getTask($taskId);
        if (!$task) {
            return ['status' => false, 'message' => '事务不存在'];
        }
        
        // 检查用户是否是创建者或参与者
        if ($task['creator_id'] != $userId && !$this->isTaskParticipant($taskId, $userId)) {
            return ['status' => false, 'message' => '您不是此事务的创建者或参与者'];
        }
        
        // 检查事务状态
        if ($task['status'] != 'pending') {
            return ['status' => false, 'message' => '此事务已完成或已过期'];
        }
        
        try {
            // 开始数据库事务
            $this->db->getConnection()->beginTransaction();
            
            // 更新事务状态
            $this->db->query(
                "UPDATE tasks SET status = 'completed', updated_at = NOW() WHERE id = ?",
                [$taskId]
            );
            
            // 更新参与者状态
            if ($task['creator_id'] != $userId) {
                $this->db->query(
                    "UPDATE task_participants SET status = 'completed', updated_at = NOW() WHERE task_id = ? AND user_id = ?",
                    [$taskId, $userId]
                );
            }
            
            // 添加通知
            $this->addTaskCompletedNotification($userId, $task['creator_id'], $taskId, $task['title']);
            
            // 获取参与者
            $participants = $this->getTaskParticipants($taskId);
            
            // 自动增加亲密度
            $friend = new Friend();
            $intimacyPoints = 1; // 默认增加1点亲密度
            $intimacyIncreased = 0;
            $allParticipants = $participants;
            
            // 将创建者也添加到参与者列表中
            $creatorInList = false;
            foreach ($allParticipants as $p) {
                if ($p['id'] == $task['creator_id']) {
                    $creatorInList = true;
                    break;
                }
            }
            
            if (!$creatorInList) {
                $creator = $this->db->fetch("SELECT id, username, nickname FROM users WHERE id = ?", [$task['creator_id']]);
                if ($creator) {
                    $allParticipants[] = $creator;
                }
            }
            
            // 所有参与者之间相互增加亲密度
            $processedPairs = [];
            
            for ($i = 0; $i < count($allParticipants); $i++) {
                for ($j = $i + 1; $j < count($allParticipants); $j++) {
                    $user1 = $allParticipants[$i]['id'];
                    $user2 = $allParticipants[$j]['id'];
                    
                    // 跳过相同的用户
                    if ($user1 == $user2) {
                        continue;
                    }
                    
                    // 检查是否已处理过这对男友
                    $pairKey = min($user1, $user2) . '-' . max($user1, $user2);
                    if (in_array($pairKey, $processedPairs)) {
                        continue;
                    }
                    $processedPairs[] = $pairKey;
                    
                    // 获取男友关系ID
                    $friendshipId = $friend->getFriendshipId($user1, $user2);
                    
                    if ($friendshipId) {
                        // 增加亲密度
                        $result = $friend->increaseIntimacy(
                            $friendshipId, 
                            $intimacyPoints, 
                            $taskId, 
                            '完成事务 "' . $task['title'] . '" 自动增加亲密度'
                        );
                        
                        if ($result['status']) {
                            $intimacyIncreased++;
                            
                            // 标记已增加亲密度
                            $this->db->query(
                                "UPDATE task_participants SET intimacy_added = 1 WHERE task_id = ? AND (user_id = ? OR user_id = ?)",
                                [$taskId, $user1, $user2]
                            );
                        }
                    }
                }
            }

            
            // 为所有参与者添加通知
            foreach ($allParticipants as $participant) {
                if ($participant['id'] != $userId) {
                    $this->addTaskCompletedNotification($userId, $participant['id'], $taskId, $task['title']);
                }
            }
            
            // 提交数据库事务
            $this->db->getConnection()->commit();
            
            $message = '事务已标记为完成';
            if ($intimacyIncreased > 0) {
                $message .= '，并自动增加了参与者之间的亲密度（每对男友+' . $intimacyPoints . '点）';
            }
            
            return ['status' => true, 'message' => $message];
        } catch (Exception $e) {
            // 回滚数据库事务
            $this->db->getConnection()->rollBack();
            return ['status' => false, 'message' => '操作失败，请稍后再试：' . $e->getMessage()];
        }
    }
    
    /**
     * 接受事务邀请
     * 
     * @param int $taskId 事务ID
     * @param int $userId 当前用户ID
     * @return array 包含状态和消息的数组
     */
    public function acceptTaskInvitation($taskId, $userId) {
        // 检查事务是否存在
        $task = $this->getTask($taskId);
        if (!$task) {
            return ['status' => false, 'message' => '事务不存在'];
        }
        
        // 检查用户是否被邀请
        $participant = $this->db->fetch(
            "SELECT * FROM task_participants WHERE task_id = ? AND user_id = ? AND status = 'invited'",
            [$taskId, $userId]
        );
        
        if (!$participant) {
            return ['status' => false, 'message' => '您没有被邀请参与此事务或已处理邀请'];
        }
        
        try {
            // 更新参与者状态
            $this->db->query(
                "UPDATE task_participants SET status = 'accepted', updated_at = NOW() WHERE task_id = ? AND user_id = ?",
                [$taskId, $userId]
            );
            
            return ['status' => true, 'message' => '已接受事务邀请'];
        } catch (Exception $e) {
            return ['status' => false, 'message' => '操作失败，请稍后再试'];
        }
    }
    
    /**
     * 拒绝事务邀请
     * 
     * @param int $taskId 事务ID
     * @param int $userId 当前用户ID
     * @return array 包含状态和消息的数组
     */
    public function rejectTaskInvitation($taskId, $userId) {
        // 检查事务是否存在
        $task = $this->getTask($taskId);
        if (!$task) {
            return ['status' => false, 'message' => '事务不存在'];
        }
        
        // 检查用户是否被邀请
        $participant = $this->db->fetch(
            "SELECT * FROM task_participants WHERE task_id = ? AND user_id = ? AND status = 'invited'",
            [$taskId, $userId]
        );
        
        if (!$participant) {
            return ['status' => false, 'message' => '您没有被邀请参与此事务或已处理邀请'];
        }
        
        try {
            // 更新参与者状态
            $this->db->query(
                "UPDATE task_participants SET status = 'rejected', updated_at = NOW() WHERE task_id = ? AND user_id = ?",
                [$taskId, $userId]
            );
            
            return ['status' => true, 'message' => '已拒绝事务邀请'];
        } catch (Exception $e) {
            return ['status' => false, 'message' => '操作失败，请稍后再试'];
        }
    }
    
    /**
     * 增加亲密度
     * 
     * @param int $taskId 事务ID
     * @param int $userId 当前用户ID
     * @param int $friendId 男友ID
     * @param int $points 增加的点数
     * @return array 包含状态和消息的数组
     */
    public function increaseIntimacy($taskId, $userId, $friendId, $points = 10) {
        // 检查事务是否存在且已完成
        $task = $this->getTask($taskId);
        if (!$task) {
            return ['status' => false, 'message' => '事务不存在'];
        }
        
        if ($task['status'] != 'completed') {
            return ['status' => false, 'message' => '只有完成的事务才能增加亲密度'];
        }
        
        // 检查用户是否是创建者或参与者
        if ($task['creator_id'] != $userId && !$this->isTaskParticipant($taskId, $userId)) {
            return ['status' => false, 'message' => '您不是此事务的创建者或参与者'];
        }
        
        // 检查男友是否是创建者或参与者
        if ($task['creator_id'] != $friendId && !$this->isTaskParticipant($taskId, $friendId)) {
            return ['status' => false, 'message' => '您选择的男友不是此事务的创建者或参与者'];
        }
        
        // 检查是否已经增加过亲密度
        $participant = $this->db->fetch(
            "SELECT * FROM task_participants WHERE task_id = ? AND user_id = ? AND intimacy_added = 1",
            [$taskId, $userId]
        );
        
        if ($participant) {
            return ['status' => false, 'message' => '您已经为此事务增加过亲密度'];
        }
        
        // 获取男友关系ID
        $friend = new Friend();
        $friendshipId = $friend->getFriendshipId($userId, $friendId);
        
        if (!$friendshipId) {
            return ['status' => false, 'message' => '您与选择的用户不是男友关系'];
        }
        
        try {
            // 开始事务
            $this->db->getConnection()->beginTransaction();
            
            // 增加亲密度
            $result = $friend->increaseIntimacy(
                $friendshipId, 
                $points, 
                $taskId, 
                '完成事务 "' . $task['title'] . '" 增加亲密度'
            );
            
            if (!$result['status']) {
                throw new Exception($result['message']);
            }
            
            // 标记已增加亲密度
            $this->db->query(
                "UPDATE task_participants SET intimacy_added = 1 WHERE task_id = ? AND user_id = ?",
                [$taskId, $userId]
            );
            
            // 提交事务
            $this->db->getConnection()->commit();
            
            return [
                'status' => true,
                'message' => '亲密度增加成功',
                'points' => $points,
                'new_intimacy' => $result['new_intimacy']
            ];
        } catch (Exception $e) {
            // 回滚事务
            $this->db->getConnection()->rollBack();
            return ['status' => false, 'message' => '增加亲密度失败，请稍后再试'];
        }
    }
    
    /**
     * 获取事务信息
     * 
     * @param int $taskId 事务ID
     * @return array|false 事务信息数组或false
     */
    public function getTask($taskId) {
        return $this->db->fetch("SELECT * FROM tasks WHERE id = ?", [$taskId]);
    }
    
    /**
     * 获取用户的事务列表
     * 
     * @param int $userId 用户ID
     * @param string $status 事务状态（all, pending, completed, expired）
     * @param int $limit 限制数量
     * @return array 事务列表
     */
    public function getUserTasks($userId, $status = 'all', $limit = 10) {
        $sql = "SELECT t.* FROM tasks t 
                LEFT JOIN task_participants tp ON t.id = tp.task_id 
                WHERE (t.creator_id = ? OR tp.user_id = ?)";
        
        $params = [$userId, $userId];
        
        if ($status != 'all') {
            $sql .= " AND t.status = ?";
            $params[] = $status;
        }
        
        $sql .= " GROUP BY t.id ORDER BY t.deadline ASC";
        
        if ($limit > 0) {
            $sql .= " LIMIT ?";
            $params[] = $limit;
        }
        
        return $this->db->fetchAll($sql, $params);
    }
    
    /**
     * 获取事务参与者
     * 
     * @param int $taskId 事务ID
     * @return array 参与者列表
     */
    public function getTaskParticipants($taskId) {
        return $this->db->fetchAll(
            "SELECT u.id, u.username, u.nickname, u.avatar, tp.status, tp.intimacy_added
             FROM task_participants tp
             JOIN users u ON tp.user_id = u.id
             WHERE tp.task_id = ?",
            [$taskId]
        );
    }
    
    /**
     * 检查用户是否是事务参与者
     * 
     * @param int $taskId 事务ID
     * @param int $userId 用户ID
     * @return bool 是否是参与者
     */
    public function isTaskParticipant($taskId, $userId) {
        $participant = $this->db->fetch(
            "SELECT * FROM task_participants WHERE task_id = ? AND user_id = ?",
            [$taskId, $userId]
        );
        
        return $participant ? true : false;
    }
    
    /**
     * 添加事务邀请通知
     * 
     * @param int $senderId 发送者ID
     * @param int $receiverId 接收者ID
     * @param int $taskId 事务ID
     * @param string $taskTitle 事务标题
     */
    private function addTaskInvitationNotification($senderId, $receiverId, $taskId, $taskTitle) {
        $sender = $this->db->fetch("SELECT username, nickname FROM users WHERE id = ?", [$senderId]);
        $senderName = $sender['nickname'] ?? $sender['username'];
        
        $content = $senderName . ' 邀请您参与事务 "' . $taskTitle . '"';
        
        $this->db->query(
            "INSERT INTO notifications (user_id, type, related_id, content) VALUES (?, 'task_invitation', ?, ?)",
            [$receiverId, $taskId, $content]
        );
    }
    
    /**
     * 添加事务完成通知
     * 
     * @param int $completerId 完成者ID
     * @param int $receiverId 接收者ID
     * @param int $taskId 事务ID
     * @param string $taskTitle 事务标题
     */
    private function addTaskCompletedNotification($completerId, $receiverId, $taskId, $taskTitle) {
        if ($completerId == $receiverId) {
            return;
        }
        
        $completer = $this->db->fetch("SELECT username, nickname FROM users WHERE id = ?", [$completerId]);
        $completerName = $completer['nickname'] ?? $completer['username'];
        
        $content = $completerName . ' 已完成事务 "' . $taskTitle . '"';
        
        $this->db->query(
            "INSERT INTO notifications (user_id, type, related_id, content) VALUES (?, 'task_completed', ?, ?)",
            [$receiverId, $taskId, $content]
        );
    }
    
    /**
     * 检查并更新过期事务
     */
    public function updateExpiredTasks() {
        $this->db->query(
            "UPDATE tasks SET status = 'expired' 
             WHERE status = 'pending' AND deadline < NOW()"
        );
    }
}
